"""
@Author：Break
@Date：2023/05/09
@Links：https://www.cnbreak.org
@Description：咸鱼之王答题助手
@Participant：
    cnbreak：https://gitee.com/cnbreak
    馒头拿来摸摸：https://gitee.com/mtnlmm
"""
import os, sys, time, shutil, win32gui, win32con, subject, logging, ctypes
from PIL import ImageGrab
from paddleocr import PaddleOCR
from fuzzywuzzy import fuzz

# 初始化
img_dir = "img"  # 初始化截图目录
if os.path.exists(img_dir):
    shutil.rmtree(img_dir)
os.makedirs(img_dir)
log_dir = "log"  # 初始化日志目录
if os.path.exists(log_dir) == False:
    os.makedirs(log_dir)
timeForFile = time.strftime('%Y%m%d_%H%M%S', time.localtime(time.time()))  # 定义时间格式

# 配置logging
logging.disable(logging.DEBUG)  # 关闭DEBUG日志的打印
# logging.disable(logging.WARNING)  # 关闭WARNING日志的打印
log_name = f"log/result_{timeForFile}.log"  # log文件名
handler = [logging.FileHandler(filename=log_name, encoding="utf-8")]  # 设置编码
logging.basicConfig(level=logging.INFO, handlers=handler)

# 获取指定窗体句柄
hwnd = win32gui.FindWindow(None, "咸鱼之王")
if hwnd == 0:
    print("未找到咸鱼之王窗口!")
    os.system("pause")  # 让控制台暂停，避免闪退
    sys.exit()  # 正常退出
else:
    print("咸鱼之王窗口句柄：", hwnd)

# 获取窗口状态，是正常在桌面上显示的还是最小化的，最小化无法获取窗口位置和大小
window_state = win32gui.GetWindowPlacement(hwnd)[1]
if window_state == win32con.SW_SHOWMINIMIZED:
    print("咸鱼之王正处于最小化的状态，请在桌面上正常显示后再运行")
    os.system("pause")  # 让控制台暂停，避免闪退
    sys.exit()  # 正常退出

# 获取窗口位置和大小,支持全分辨率和全缩放比例，贡献者：馒头拿来摸摸，Gitee：https://gitee.com/mtnlmm  start
def get_window_rect(hwnd):
    """
    使用了Windows系统的API函数DwmGetWindowAttribute来获取窗口的扩展框架边界，也就是窗口的位置和大小。
    如果系统支持DwmGetWindowAttribute函数，则通过该函数获取窗口位置信息。如果系统不支持该函数，则返回None。
    函数接受一个窗口句柄hwnd作为参数，调用DwmGetWindowAttribute函数获取矩形rect的左上角和右下角坐标位置，
    最后返回一个四元组(left, top, right, bottom)，表示窗口的位置和大小
    @Author：馒头拿来摸摸
    @Date：2023/06/11
    @Links：https://gitee.com/mtnlmm
    """
    try:
        f = ctypes.windll.dwmapi.DwmGetWindowAttribute
    except WindowsError:
        f = None
    if f:
        rect = ctypes.wintypes.RECT()
        DWMWA_EXTENDED_FRAME_BOUNDS = 9
        f(
            ctypes.wintypes.HWND(hwnd),
            ctypes.wintypes.DWORD(DWMWA_EXTENDED_FRAME_BOUNDS),
            ctypes.byref(rect),
            ctypes.sizeof(rect)
        )
        return rect.left, rect.top, rect.right, rect.bottom
left, top, right, bottom = get_window_rect(hwnd)
# 获取窗口位置和大小,支持全分辨率和全缩放比例，贡献者：馒头拿来摸摸，Gitee：https://gitee.com/mtnlmm  end

# 主要工作函数
def run(left, top, right, bottom, num):
    # 截取窗口上部三分之一区域
    top += 110
    height = int((bottom - top) / 3) - 120
    img = ImageGrab.grab((left, top, right, top + height))
    img_name = "img/xyzw" + str(num) + ".jpg"
    img.save(img_name)  # 保存截取的图片内容

    # OCR识别文字
    ocr = PaddleOCR(use_angle_cls=True, lang="ch")
    result = ocr.ocr(img_name, cls=True)
    # 输出结果
    text = ""
    for idx in range(len(result)):
        res = result[idx]
        for line in res:
            text += (line[1][0])

    # 计算内容相似度
    # 定义一个函数用来计算相似度并返回相似度最高的元素
    def find_most_similar(data, text):
        max_score = -1
        result = None
        for item in data:
            for key, value in item.items():
                score = fuzz.token_sort_ratio(text, value)
                if score > max_score:
                    max_score = score
                    result = item
        return result

    result = find_most_similar(subject.properties, text)  # 计算结果
    print(time.strftime('%H:%M:%S', time.localtime(time.time())) + f"：|题目|{result['name']}  |结果|" + result["value"])  # 打印结果
    logging.info(time.strftime('%H:%M:%S', time.localtime(time.time())) + f"：|ocr|{text}  |原题|{result['name']}  |结果|" + result["value"])  # 记录日志,写入log


num = 0
while True:  # 不停运行
    # time.sleep(1)  # 时间间隔
    run(left, top, right, bottom, num)  # 主要工作函数
    num += 1
